<?php

class CookieSession {

    private $secret; // string for us to do hash
    private $cookie_name; // name of the cookie to be stored on browser
    private $cookie_params; // session cookie params
    private $session_id;

    public function __construct($secret, $name = '_session_id', $cookie_name = '_session_data') {

        $this->cookie_params = session_get_cookie_params();
        $this->secret = $secret;
        $this->cookie_name = $cookie_name;

        // set the name of the session
        session_name($name);

        // register the functions into mini
        Response::hook(Response::BEFORE_PROCESS_HOOK, array($this, 'read'));
        Response::hook(Response::BEFORE_SEND_HOOK, array($this, 'write'));

        // start the session if it's not automatically started
        session_start();

        $this->session_id = session_id();
    }

    public function read() {
        $cookie_string = '';

        if (!isset($_COOKIE[$this->cookie_name])) {
            return;
        }

        $cookie_string = $_COOKIE[$this->cookie_name];

        $values = json_decode(base64_decode($cookie_string));
        if (count($values) !== 2 ) {
            // hum... the cookie value isn't right
            return;
        }

        $session_id_len = strlen($this->session_id);
        $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->secret, base64_decode($values[0]), MCRYPT_MODE_CFB, base64_decode($values[1]));
        if (substr($decrypted, 0, $session_id_len) !== $this->session_id) {
            // hum... the session id didn't match. ignore the session data
            return;
        }
        session_decode(substr($decrypted, $session_id_len));
    }

    public function write() {
        $data = $this->session_id . session_encode();
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
        $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->secret, $data, MCRYPT_MODE_CFB, $iv);
        setrawcookie($this->cookie_name,
                     base64_encode(json_encode(array(base64_encode($encrypted), base64_encode($iv)))),
                     $this->cookie_params['lifetime'],
                     $this->cookie_params['path'],
                     $this->cookie_params['domain'],
                     $this->cookie_params['secure'],
                     $this->cookie_params['httponly']);
        session_destroy();
    }

}
